﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using WowRaidListTracker.DAL;

namespace WowRaidListTracker.core.Application
{
    public class MemberManager : Manager
    {
        public delegate void MemberUpdateEventHandler(object sender, EventArgs e);

        private event MemberUpdateEventHandler memberUpdated;
        public event MemberUpdateEventHandler MemberUpdated
        {
            add
            {
                memberUpdated += value;
            }
            remove
            {
                memberUpdated -= value;
            }
        }

        private List<RaidMember> raidMembersList;
        public List<RaidMember> RaidMembersList
        {
            get
            {
                if (raidMembersList == null)
                {
                    raidMembersList = new List<RaidMember>();
                    return raidMembersList;
                }
                else
                {
                    return raidMembersList;
                }
            }
        }

        public MemberManager()
            : base()
        {
            LoadCharacterClasses();
            LoadCharacterSpecializations();
            LoadMembers();
        }

        public void LoadCharacterClasses()
        {
            CharacterClass.PopulateCharacterClassCollection(dal);
        }

        public void LoadCharacterSpecializations()
        {
            CharacterSpecialization.PopulateCharacterSpecializationCollection(dal);
        }

        public void LoadMembers()
        {
            string sql = CRUDReader.Crud.get("RaidMembers", CRUDReader.QUDType.Select);
            object executeResult = dal.Execute(sql, SQLiteQueryType.STANDARDQUERY);
            raidMembersList = new List<RaidMember>();

            if (typeof(DataTable) == executeResult.GetType())
            {
                DataTable result = executeResult as DataTable;
                foreach (DataRow dr in result.Rows)
                {
                    raidMembersList.Add(new RaidMember(dr));
                }
            }
            else
            {
                throw new InvalidTypeException("The type returned by the ListTrackerDal.Execute method was not correct");
            }
        }

        public void AddMember(string name, int classId, int specialization1,
            int specialization2)
        {
            AddMember(name, classId, specialization1, specialization2, 5);
        }

        public void AddMember(string name, int classId, int specialization1,
            int specialization2, int specialization3)
        {
            RaidMember r = new RaidMember()
            {
                Name = name,
                CharacterClassId = classId,
                PrimarySpecialization = specialization1,
                SecondarySpecialization = specialization2,
                TertiarySpecialization = specialization3
            };

            r.AddMember();

            OnMemberUpdated(r);
        }

        public void AddMember(RaidMember rm)
        {
            rm.AddMember();
            RaidMembersList.Add(rm);
            OnMemberUpdated(rm);
        }

        public void UpdatePresence(int memberId, bool isPresent)
        {
            // find the correct raid member object
            foreach (RaidMember r in RaidMembersList)
            {
                if (r.Id == memberId)
                {
                    r.UpdatePresence(isPresent);
                    r.IsPresent = isPresent;
                    break;
                }
            }
        }

        public NonQueryResult RemoveMember(RaidMember r)
        {
            return r.RemoveMember();
        }

        private void OnMemberUpdated(RaidMember r)
        {
            if (memberUpdated != null)
            {
                memberUpdated(r, new EventArgs());
            }
        }
    }
}
